home *** CD-ROM | disk | FTP | other *** search
- ;------------------------------------------------------------------------------
- ;
- ; File : BitStream.a
- ;
- ; Author : Stéphane TAVENARD
- ;
- ; $VER: BitStream.a 1.2 (29/07/1995)
- ;
- ; (C) Copyright 1995-1995 Stéphane TAVENARD
- ; All Rights Reserved
- ;
- ; #Rev| Date | Comment
- ; ----|----------|--------------------------------------------------------
- ; 0 |12/04/1995| Initial revision ST
- ; 1 |03/06/1995| First release (no more C code) ST
- ; 2 |23/06/1995| Aminet release ST
- ; 3 |29/07/1995| Added a6 register save ST
- ;
- ; ------------------------------------------------------------------------
- ;
- ; BitStream files handling
- ;
- ;------------------------------------------------------------------------------
-
- IFND INCLUDE_SOURCE
- incdir "include:"
- include "exec/funcdef.i"
- include "exec/exec.i"
- include "exec/exec_lib.i"
- include "dos/dos.i"
- include "dos/dos_lib.i"
- XREF _DOSBase
- ENDC
-
- include "bitstream.i"
-
- XDEF @BSTR_open
- XDEF @BSTR_close
- XDEF @BSTR_rewind
- XDEF @BSTR_end
- XDEF @BSTR_seek_tell
- XDEF @BSTR_read_bit
- XDEF @BSTR_read_bits
- XDEF @BSTR_read_signed_bits
- XDEF @BSTR_skip_bits
- XDEF @BSTR_read3_bits
- XDEF @BSTR_read2_bits
- XDEF @BSTR_seek_sync
- ;
- IFND INCLUDE_SOURCE
- CALLEXEC MACRO
- move.l (_SysBase).w,a6
- jsr _LVO\1(a6)
- ENDM
- _SysBase EQU 4
-
- CALLDOS MACRO
- move.l _DOSBase,a6
- jsr _LVO\1(a6)
- ENDM
- ENDC
-
- ;
- section ASMCODE,code
-
-
- ; Close a bitstream file
- ;
- ; a0 = bitstream structure ptr
- ;
- @BSTR_close
- movem.l a2/a6/d2,-(sp)
- move.l a0,a2
- tst.l a2
- beq BSTR_close9
- move.l BSTR_file_ptr(a2),d1
- beq BSTR_close7
- CALLDOS Close
- clr.l BSTR_file_ptr(a2)
- BSTR_close7 move.l BSTR_buffer(a2),a1
- tst.l a1
- beq BSTR_close8
- move.l BSTR_buffer_size(a2),d0
- CALLEXEC FreeMem
- clr.l BSTR_buffer(a2)
- BSTR_close8 move.l a2,a1
- moveq.l #BSTR_SIZEOF,d0
- CALLEXEC FreeMem
- BSTR_close9 movem.l (sp)+,a2/a6/d2
- rts
-
- ; Open a bitstream file
- ;
- ; a0 = name
- ; d0.l = buffer size
- ; d1.l = access mode
- ; -> d0.l = bitstream structure ptr (=0 if error)
- @BSTR_open
- movem.l a2/a6/d2,-(sp)
- move.l a0,name
- move.l d0,buffer_size
- move.l d1,mode
- clr.l bstr_ptr
- cmp.l #BSTR_MODE_READ,d1
- bne BSTR_open8 ; not implemented yet
-
- moveq.l #BSTR_SIZEOF,d0
- move.l #MEMF_ANY|MEMF_CLEAR,d1
- CALLEXEC AllocMem
- move.l d0,bstr_ptr
- beq BSTR_open7 ; fail
- move.l d0,a2
- move.l buffer_size,d0
- move.l d0,BSTR_buffer_size(a2)
- move.l #MEMF_ANY,d1
- CALLEXEC AllocMem
- move.l d0,BSTR_buffer(a2)
- beq BSTR_open7 ; fail
- move.l mode,BSTR_mode(a2)
- move.l name,d1
- move.l #MODE_OLDFILE,d2
- CALLDOS Open
- move.l d0,BSTR_file_ptr(a2)
- beq BSTR_open7 ; fail
- move.l a2,d0
- bra BSTR_open9 ; success
- BSTR_open7
- move.l bstr_ptr,a0
- bsr @BSTR_close
- BSTR_open8 clr.l d0
- BSTR_open9 movem.l (sp)+,a2/a6/d2
- rts
-
- ; Seek to start of the bitstream
- ;
- ; a0 = bitstream structure ptr
- ; -> d0.l = 0 if fail
- ;
- @BSTR_rewind movem.l a2/a6/d2-d3,-(sp)
- tst.l a0
- move.l a0,a2
- beq BSTR_rewind9
- move.l BSTR_file_ptr(a2),d1
- moveq.l #0,d2
- moveq.l #OFFSET_BEGINNING,d3
- CALLDOS Seek
- tst.l d0
- bmi BSTR_rewind8
- clr.l BSTR_current_bit_index(a2)
- clr.l BSTR_remaining_bits(a2)
- clr.l BSTR_bitstream_size(a2)
- clr.l BSTR_end_of_stream(a2)
- moveq.l #1,d0
- bra BSTR_rewind9
- BSTR_rewind8 clr.l d0
- BSTR_rewind9 movem.l (sp)+,a2/a6/d2-d3
- rts
-
- ; Test if end of bistream is reached
- ;
- ; a0 = bitstream structure ptr
- ; -> d0.l = 0 if not end of bitstream
- @BSTR_end
- move.l BSTR_end_of_stream(a0),d0
- rts
-
- ; Get the current seek bit of bistream
- ; a0 = bitstream structure ptr
- ; -> d0.l = seek value
- @BSTR_seek_tell
- move.l BSTR_bitstream_size(a0),d0
- rts
-
-
- ; Fill in the read buffer of a bitstream
- ;
- ; a0 = bitstream
- BSTR_fill_buffer
- movem.l d0-d7/a0-a6,-(sp)
- tst.l BSTR_end_of_stream(a0)
- bne BSTR_fill_buffer9 ; end of stream !
- move.l BSTR_buffer(a0),a1
- move.l BSTR_buffer_size(a0),d3
- move.l BSTR_current_bit_index(a0),d0
- asr.l #3,d0 ; current byte index
- lea.l (a1,d0.l),a2 ; last unread bytes
- and.l #7,BSTR_current_bit_index(a0) ; reset current bit index
- move.l BSTR_remaining_bits(a0),d0
- BSTR_fill_buffer1 tst.l d0
- ble BSTR_fill_buffer2 ; no remaining bits
- move.b (a2)+,(a1)+ ; copy remaining bytes
- subq.l #8,d0
- subq.l #1,d3 ; bytes to read --
- bra BSTR_fill_buffer1
- BSTR_fill_buffer2 move.l a0,-(sp)
- move.l BSTR_file_ptr(a0),d1
- move.l a1,d2 ; read buffer
- CALLDOS Read
- move.l (sp)+,a0
- asl.l #3,d0 ; read bytes * 8 -> read bits
- ble BSTR_fill_buffer8 ; read bits <= 0 -> end of stream
- add.l d0,BSTR_remaining_bits(a0)
- bra BSTR_fill_buffer9
- BSTR_fill_buffer8 move.l #-1,BSTR_end_of_stream(a0) ; end of stream !
- BSTR_fill_buffer9 movem.l (sp)+,d0-d7/a0-a6
- rts
-
-
- ; Read 1 bit (unsigned) from a bitstream
- ;
- ; a0 = bitstream
- ; -> d0 = bit value
- ; a0 is preserved
- ; a1 & d1 are affected
- ;
- @BSTR_read_bit
- moveq.l #1,d1
- ; bra @BSTR_read_bits
-
- ; Read some bits (unsigned) from a bitstream
- ;
- ; a0 = bitstream
- ; d1 = bit count (max=32)
- ; -> d0 = bits value (=0 if bitstream is empty)
- ; a0 & d1 are preserved
- ; a1 is affected
- ;
- @BSTR_read_bits
- BSTR_read_bits1 sub.l d1,BSTR_remaining_bits(a0)
- bmi.s BSTR_read_bits2 ; no more bits available
- move.l BSTR_current_bit_index(a0),d0
- move.l BSTR_buffer(a0),a1
- bfextu (a1){d0:d1},d0 ; read bits -> d0
- add.l d1,BSTR_current_bit_index(a0)
- add.l d1,BSTR_bitstream_size(a0)
- rts
- BSTR_read_bits2 add.l d1,BSTR_remaining_bits(a0) ; restore old count
- bsr BSTR_fill_buffer
- tst.l BSTR_end_of_stream(a0)
- beq BSTR_read_bits1 ; not end of bitstream
- BSTR_read_bits9 moveq.l #0,d0
- rts
-
- ; Read some bits (signed) from a bitstream
- ;
- ; a0 = bitstream
- ; d1 = bit count (max=32)
- ; -> d0 = bits value (=0 if bitstream is empty)
- ; a0 & d1 are preserved
- ; a1 is affected
- ;
- @BSTR_read_signed_bits
- BSTR_read_sbits1 sub.l d1,BSTR_remaining_bits(a0)
- bmi BSTR_read_sbits2 ; no more bits available
- move.l BSTR_current_bit_index(a0),d0
- move.l BSTR_buffer(a0),a1
- bfexts (a1){d0:d1},d0 ; read signed bits -> d0
- add.l d1,BSTR_current_bit_index(a0)
- add.l d1,BSTR_bitstream_size(a0)
- rts
- BSTR_read_sbits2 add.l d1,BSTR_remaining_bits(a0) ; restore old count
- bsr BSTR_fill_buffer
- tst.l BSTR_end_of_stream(a0)
- beq BSTR_read_sbits1 ; not end of bitstream
- BSTR_read_sbits9 moveq.l #0,d0
- rts
-
- ; Skip some bits from a bitstream
- ;
- ; a0 = bitstream
- ; d1 = length (can be > 32)
- ; -> d0 = bit skipped count
- ; a0, a1 & d1 are preserved
- ;
- @BSTR_skip_bits
- BSTR_skip_bits1 sub.l d1,BSTR_remaining_bits(a0)
- bmi.s BSTR_skip_bits2 ; no more bits available
- add.l d1,BSTR_current_bit_index(a0)
- add.l d1,BSTR_bitstream_size(a0)
- move.l d1,d0
- rts
- BSTR_skip_bits2 add.l d1,BSTR_remaining_bits(a0) ; restore old count
- bsr BSTR_fill_buffer
- tst.l BSTR_end_of_stream(a0)
- beq BSTR_skip_bits1 ; not end of bitstream
- clr.l d0
- rts
-
- ; Read three bits-packets (unsigned) from a bitstream
- ;
- ; a0 = bitstream
- ; d1 = bit count for each packet (max=32)
- ; -> d4, d5, d6 = bits values packets
- ; a0 & d1 are preserved
- ; a1 & d2 are modified !!!
- ;
- @BSTR_read3_bits
- BSTR_read3_bits1 move.l d1,d2
- add.l d2,d2
- add.l d1,d2 ; d2 = 3*d1
- sub.l d2,BSTR_remaining_bits(a0)
- bmi.s BSTR_read3_bits2 ; no more bits available
- move.l BSTR_current_bit_index(a0),d0
- move.l BSTR_buffer(a0),a1
- bfextu (a1){d0:d1},d4 ; read bits -> d4
- add.l d1,d0 ; next packet
- bfextu (a1){d0:d1},d5 ; read bits -> d5
- add.l d1,d0 ; next packet
- bfextu (a1){d0:d1},d6 ; read bits -> d6
- add.l d2,BSTR_current_bit_index(a0)
- add.l d2,BSTR_bitstream_size(a0)
- rts
- BSTR_read3_bits2 add.l d2,BSTR_remaining_bits(a0) ; restore old count
- bsr BSTR_fill_buffer
- tst.l BSTR_end_of_stream(a0)
- beq BSTR_read3_bits1 ; not end of bitstream
- moveq.l #0,d4
- move.l d4,d5
- move.l d4,d6
- rts
-
- ; Read two bits-packets (unsigned) from a bitstream
- ;
- ; a0 = bitstream
- ; d1 = bit count for each packet (max=32)
- ; -> d4, d5 = bits values packets
- ; a0 & d1 are preserved
- ; a1 & d2 are modified !!!
- ;
- @BSTR_read2_bits
- BSTR_read2_bits1 move.l d1,d2
- add.l d2,d2 ; d2 = 2*d1
- sub.l d2,BSTR_remaining_bits(a0)
- bmi.s BSTR_read2_bits2 ; no more bits available
- move.l BSTR_current_bit_index(a0),d0
- move.l BSTR_buffer(a0),a1
- bfextu (a1){d0:d1},d4 ; read bits -> d4
- add.l d1,d0 ; next packet
- bfextu (a1){d0:d1},d5 ; read bits -> d5
- add.l d2,BSTR_current_bit_index(a0)
- add.l d2,BSTR_bitstream_size(a0)
- rts
- BSTR_read2_bits2 add.l d2,BSTR_remaining_bits(a0) ; restore old count
- bsr BSTR_fill_buffer
- tst.l BSTR_end_of_stream(a0)
- beq BSTR_read2_bits1 ; not end of bitstream
- moveq.l #0,d4
- move.l d4,d5
- rts
-
- ; Seek to the next sync. 8-bit aligned pattern
- ;
- ; a0 = bitstream structure ptr
- ; d0.l = sync. value
- ; d1.l = sync. length
- ; -> d0.l = 0 if not found
- ;
- @BSTR_seek_sync
- movem.l a2/d2-d4,-(sp)
- move.l d0,d2
- move.l d1,d3
- clr.l d4
- bset d1,d4
- subq.l #1,d4 ; d4 = bits mask
- move.l BSTR_bitstream_size(a0),d0
- and.l #7,d0
- beq BSTR_seek_sync3 ; already 8-bit aligned
- moveq.l #8,d1
- sub.l d0,d1 ; d1 = bits to skip
- bsr @BSTR_skip_bits
- BSTR_seek_sync3 move.l d3,d1
- bsr @BSTR_read_bits ; read first packet
- move.l d0,d3
- moveq.l #8,d1
- BSTR_seek_sync5 cmp.l d3,d2
- beq BSTR_seek_sync8 ; ok sync. found
- tst.l BSTR_end_of_stream(a0)
- bne BSTR_seek_sync7 ; end of bitstream reached
- lsl.l d1,d3
- and.l d4,d3
- bsr @BSTR_read_bits ; read next 8 bits
- or.l d0,d3 ; update bit packet
- bra BSTR_seek_sync5
- BSTR_seek_sync7 clr.l d0
- bra BSTR_seek_sync9
- BSTR_seek_sync8 moveq.l #-1,d0
- BSTR_seek_sync9 movem.l (sp)+,a2/d2-d4
- rts
-
- section ASMVARS,bss
-
- even
-
- name ds.l 1
- buffer_size ds.l 1
- mode ds.l 1
- bstr_ptr ds.l 1
-
-